// <copyright file="DataSourceBase.cs" company="YUIAsp.Net">
// Copyright (c) 2009 All Right Reserved
// </copyright>
// <author>raul popescu</author>
// <email>dev@yuiasp.net</email>
// <date>2009-01-30</date>
// <summary>YUIAsp.Net File</summary>

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using YUIAspNet.Common;

namespace YUIAspNet
{
    /// <summary>
    /// Base class for a data source.
    /// </summary>
    public abstract class DataSourceBase
    {
        private List<string> _keys;
        private List<object[]> _values;
        private Dictionary<string, object> _additionalItems;

        /// <summary>
        /// Gets the keys.
        /// </summary>
        /// <value>The keys.</value>
        protected IList<string> Keys 
        {
            get { return _keys; }
        }

        /// <summary>
        /// Gets the values.
        /// </summary>
        /// <value>The values.</value>
        protected IList<object[]> Values
        {
            get { return _values; }
        }

        /// <summary>
        /// Gets the additional items.
        /// </summary>
        /// <value>The additional items.</value>
        protected Dictionary<string, object> AdditionalItems
        {
            get { return _additionalItems; }
        }

        /// <summary>
        /// Gets the data URL.
        /// </summary>
        /// <value>The data URL.</value>
        protected Uri DataUrl { get; set; }


        /// <summary>
        /// Initializes a new instance of the <see cref="DataSourceBase"/> class.
        /// </summary>
        /// <param name="sourceType">Type of the source.</param>
        protected DataSourceBase(DataSourceType sourceType)
        {
            DataSourceType = sourceType;

            _keys = new List<string>();
            _values = new List<object[]>();
            _additionalItems = new Dictionary<string, object>();
        }

        /// <summary>
        /// Gets or sets the type of the data source.
        /// </summary>
        /// <value>The type of the data source.</value>
        public DataSourceType DataSourceType { get; protected set; }

        /// <summary>
        /// Serializes this instance.
        /// </summary>
        /// <returns></returns>
        public StringBuilder Serialize()
        {
            ValidateDataSource();

            StringBuilder sbJson = new StringBuilder("{");
            string keys = string.Join("\",\"",_keys.ToArray());
            keys = keys.Insert(0, "[\"");
            keys += "\"]";
            sbJson.Append("\"Columns\": ").Append(keys);

            sbJson.Append(",");

            StringBuilder sbSpecific = SerializeSpecificData();
            if(sbSpecific != null)
                sbJson.Append(sbSpecific);
            
            return sbJson.Append("}");
        }

        /// <summary>
        /// Serializes the specific properties foreach implementor.
        /// </summary>
        /// <returns></returns>
        protected abstract StringBuilder SerializeSpecificData();

        /// <summary>
        /// Validates the data source.
        /// </summary>
        private void ValidateDataSource()
        {
            if (this._keys.Count == 0)
                throw new InvalidOperationException("You have to specify at least one column for the datasource !");
        }

        /// <summary>
        /// Formats the value.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <returns></returns>
        protected static string FormatValue(object item)
        {
            Type type = item.GetType();
            if (type == typeof(DateTime))
                return YUIJavascriptSerializer.SerializeDate((DateTime)item);
            if(type == typeof(int))
                return item.ToString();
            return string.Format(CultureInfo.InvariantCulture, "\"{0}\"", YUIControlDescriptor.QuoteString(item.ToString()));
        }
    }
}
